package com.qys.livesMall.anchor.service.impl;

import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qys.livesMall.anchor.enums.AnchorApplyStatusEnum;
import com.qys.livesMall.anchor.enums.AnchorMessageEnum;
import com.qys.livesMall.anchor.mapper.H2AnchorApplyMapper;
import com.qys.livesMall.anchor.model.dto.H2AnchorApplyDTO;
import com.qys.livesMall.anchor.model.dto.H2AnchorApproveDTO;
import com.qys.livesMall.anchor.model.dto.H2AnchorContractDTO;
import com.qys.livesMall.anchor.model.entity.H2Anchor;
import com.qys.livesMall.anchor.model.entity.H2AnchorApply;
import com.qys.livesMall.anchor.model.vo.AnchorContractVO;
import com.qys.livesMall.anchor.service.H2AnchorApplyService;
import com.qys.livesMall.anchor.service.H2AnchorService;
import com.qys.livesMall.app.user.enums.SmsEnum;
import com.qys.livesMall.app.user.model.entity.AppUserLevel;
import com.qys.livesMall.app.user.model.entity.H2AppUser;
import com.qys.livesMall.app.user.service.AppUserLevelService;
import com.qys.livesMall.app.user.service.IH2AppUserService;
import com.qys.livesMall.app.user.utils.SmsUtil;
import com.qys.livesMall.cache.RedisCache;
import com.qys.livesMall.common.exception.QysException;
import com.qys.livesMall.common.message.MessageServer;
import com.qys.livesMall.common.result.R;
import com.qys.livesMall.framework.utils.SecurityUtils;
import com.qys.livesMall.open.enums.PushMessageTypeEnum;
import com.qys.livesMall.open.modal.dto.app.PushUserDeviceContentDTO;
import com.qys.livesMall.open.modal.dto.mail.PushAllDeviceDTO;
import com.qys.livesMall.open.modal.dto.mail.PushTitleDTO;
import com.qys.livesMall.open.service.PushUserDeviceService;
import com.qys.livesMall.system.model.entity.H2SysConfig;
import com.qys.livesMall.system.model.entity.template.H2Template;
import com.qys.livesMall.system.service.H2TemplateService;
import com.qys.livesMall.system.service.IH2SysConfigService;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.concurrent.Executors;

/**
 * 主播申请信息表(H2AnchorApply)表服务实现类
 *
 * @author yxh
 * @since 2023-06-16 09:46:15
 */
@Service
public class H2AnchorApplyServiceImpl extends ServiceImpl<H2AnchorApplyMapper, H2AnchorApply> implements H2AnchorApplyService {

    /**
     * 模板编号
     */
    public static final String ANCHOR = "anchor";

    @Autowired
    private MessageServer messageServer;
    @Autowired
    private H2TemplateService templateService;
    @Autowired
    private H2AnchorService anchorService;
    @Autowired
    private IH2AppUserService userService;
    @Autowired
    private AppUserLevelService appUserLevelService;
    @Autowired
    private RedisCache redisCache;
    @Resource
    private PushUserDeviceService pushUserDeviceService;
    @Resource
    private IH2SysConfigService ih2SysConfigService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<?> submit(H2AnchorApplyDTO dto) {

        //短信和邮箱验证
        String emailCode = dto.getEmailCode();
/*        H2SysConfig h2SysConfig=ih2SysConfigService.getConfigByKey("is_open_phone_check");
        if (null != h2SysConfig && h2SysConfig.getValue().equals("true")){*/
            String smsCode = dto.getSmsCode();
            if(!"666665".equals(smsCode)){
                if(!SmsUtil.verifyCode(SmsEnum.AHCNOR_APPLY, dto.getPhone(), smsCode)){
                    throw new QysException("smsCode error");
                }
            }
 //       }

/*        if (!"666665".equals(emailCode)){
            String emailCodeByCache = redisCache.getCacheObject("mail:anchorApply" + dto.getEmail());
            if (!emailCode.equals(emailCodeByCache)){
                throw new QysException(MessageUtils.message("shop.mail.error"));
            }
        }*/

        //登录用户
        Long userId = SecurityUtils.getUserId();
        H2AppUser appUser = userService.getById(userId);

        //判断是否有权限
        AppUserLevel userLevel = appUserLevelService.getById(appUser.getUserLevelId());
        if(userLevel == null || 1 != userLevel.getApplyAnchor()){
            return messageServer.failMsg(AnchorMessageEnum.NO_PERMISSION);
        }

        //重复提交校验
        LambdaQueryWrapper<H2AnchorApply> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(H2AnchorApply::getUserId, userId).ne(H2AnchorApply::getStatus,AnchorApplyStatusEnum.FAIL.getCode());
        long count = count(queryWrapper);
        if(count > 0){
            return messageServer.failMsg(AnchorMessageEnum.DUPLICATE_APPLICATION);
        }


        //参数校验
        AnchorMessageEnum anchorMessageEnum = this.parameterCheck(dto);
        if(null != anchorMessageEnum){
            return messageServer.failMsg(anchorMessageEnum);
        }


        //数据封装
        H2AnchorApply apply = new H2AnchorApply();
        BeanUtils.copyProperties(dto,apply);
        apply.setUserId(userId);
        apply.setAvatar(appUser.getAvatar());

        //保存申请表数据
        save(apply);

        //保存主播表数据
        H2Anchor one = anchorService.getOne(Wrappers.<H2Anchor>lambdaQuery().eq(H2Anchor::getUserId, userId));

        H2Anchor anchor = new H2Anchor();
        anchor.setUserId(userId);
        anchor.setAnchorName(dto.getFirstName() + dto.getLastName());
        anchor.setPhone(dto.getPhone());
        anchor.setCreateBy(SecurityUtils.getUsername());
        anchor.setUpdateBy(SecurityUtils.getUsername());
        anchor.setUserName(appUser.getUserName());
        if(null == one){
            anchorService.save(anchor);
        }else {
            anchor.setId(one.getId());
            anchor.setApplyStatus(0);
            anchorService.updateById(anchor);
        }
        return R.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R approve(H2AnchorApproveDTO dto) {

        //获取申请的当前状态
        LambdaQueryWrapper<H2AnchorApply> h2AnchorApplyLambdaQueryWrapper = new LambdaQueryWrapper<>();
        h2AnchorApplyLambdaQueryWrapper.eq(H2AnchorApply::getUserId, dto.getUserId()).ne(H2AnchorApply::getStatus,AnchorApplyStatusEnum.FAIL.getCode());
        H2AnchorApply apply = getOne(h2AnchorApplyLambdaQueryWrapper);
        if(null == apply){
            throw new QysException(AnchorMessageEnum.NONE_APPLE);
        }
        Integer status = apply.getStatus();

        //当状态是已完成或者未通过则不能再次审批
        if(AnchorApplyStatusEnum.AWAIT_EXAMINE.getCode() != status ){
            throw new QysException(AnchorMessageEnum.IS_COMPLETED);
        }

        LambdaUpdateWrapper<H2AnchorApply> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(H2AnchorApply::getUserId, dto.getUserId()).ne(H2AnchorApply::getStatus,AnchorApplyStatusEnum.FAIL.getCode());;
        H2AnchorApply newApply = new H2AnchorApply();
        switch (dto.getStatus()) {
            //通过
            case 1 -> newApply.setStatus(status + 1);
            //拒绝
            case 2 -> newApply.setStatus(AnchorApplyStatusEnum.FAIL.getCode());
        }
        update(newApply,updateWrapper);

        //审批流程后更新主播表审批状态数据
        LambdaUpdateWrapper<H2Anchor> h2AnchorLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        h2AnchorLambdaUpdateWrapper.eq(H2Anchor::getUserId, dto.getUserId());

        H2Anchor anchor = new H2Anchor();
        anchor.setApplyStatus(1 == dto.getStatus() ? 2 : 1);
        //修改用户信息
        if (1 == dto.getStatus()) {
//            anchor.setCarNum(apply.getCarNum());
            anchor.setCarAfter(apply.getCarAfter());
            anchor.setCarBefore(apply.getCarBefore());
            anchor.setEmail(apply.getEmail());
            anchor.setPhone(apply.getPhone());
            anchor.setUpdateTime(LocalDateTime.now());
        }
        anchorService.update(anchor,h2AnchorLambdaUpdateWrapper);

        if (1 == dto.getStatus()) {
            Executors.newFixedThreadPool(1).execute(() -> {
                PushAllDeviceDTO pushAllDeviceDTO=new PushAllDeviceDTO();
                PushUserDeviceContentDTO pushUserDeviceContentDTO=new PushUserDeviceContentDTO();
                pushUserDeviceContentDTO.setType(PushMessageTypeEnum.NOTICE_ALL);
                H2AppUser appUser = userService.getById(apply.getUserId());
                PushTitleDTO pushTitleDTO=new PushTitleDTO();
                pushTitleDTO.setChinese("恭喜 "+appUser.getNickName()+" 成为新主播");
                pushTitleDTO.setEnglish("Congratulations to "+appUser.getNickName()+" on becoming a new anchor");
                pushAllDeviceDTO.setTitle(pushTitleDTO);
                JSONObject json = new JSONObject();
                json.putOnce("chinese","恭喜 "+appUser.getNickName()+" 成为新主播");
                json.putOnce("english","Congratulations to "+appUser.getNickName()+" on becoming a new anchor");
                pushUserDeviceContentDTO.setData(json.toString());
                pushAllDeviceDTO.setContent(pushUserDeviceContentDTO);
                pushUserDeviceService.pushAllUserDevice(pushAllDeviceDTO);
            });
        }
        return R.ok();
    }

    @Override
    public AnchorContractVO getContract() {
        Long userId = SecurityUtils.getUserId();

        //获取申请
        LambdaQueryWrapper<H2AnchorApply> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(H2AnchorApply::getUserId, userId).ne(H2AnchorApply::getStatus,AnchorApplyStatusEnum.FAIL.getCode());;
        H2AnchorApply apply = getOne(queryWrapper);
        if(null == apply){
            return null;
        }
        if(apply.getStatus() != AnchorApplyStatusEnum.AWAIT_SIGN.getCode()){
            throw new QysException(AnchorMessageEnum.NOT_PASS);
        }

        //获取主播合同模板
        LambdaQueryWrapper<H2Template> templateQueryWrapper = new LambdaQueryWrapper<>();
        templateQueryWrapper.eq(H2Template::getCode,"anchor");
        templateQueryWrapper.eq(H2Template::getType,"anchor");
        H2Template template = templateService.getOne(templateQueryWrapper);

        //处理合同细节
        String languageTag = LocaleContextHolder.getLocale().toLanguageTag();
        String templateStr = languageTag.contains("en") ? template.getEnTemplate() : template.getTemplate();;
        String newTemplateStr = templateStr
                .replace("{startTime}", LocalDate.now().toString())
                .replace("{endTime}", LocalDate.now().plusMonths(6).toString())
                .replace("{monNum}", "6")
                .replace("{userName}", SecurityUtils.getUsername());

        //封装返回体
        AnchorContractVO contractVO = new AnchorContractVO();
        contractVO.setContract(newTemplateStr);
        contractVO.setContractId(String.valueOf(template.getId()));
        contractVO.setAnchorName(apply.getFirstName() + apply.getLastName());
        return contractVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void conclude(H2AnchorContractDTO dto) {

        Long userId = SecurityUtils.getUserId();

        //获取申请
        LambdaQueryWrapper<H2AnchorApply> applyQueryWrapper = new LambdaQueryWrapper<>();
        applyQueryWrapper.eq(H2AnchorApply::getUserId, userId).ne(H2AnchorApply::getStatus,AnchorApplyStatusEnum.FAIL.getCode());
        H2AnchorApply apply = getOne(applyQueryWrapper);
        if(AnchorApplyStatusEnum.AWAIT_SIGN.getCode() != apply.getStatus()){
            throw new QysException(AnchorMessageEnum.NOT_PASS);
        }

        //获取合同
        LambdaQueryWrapper<H2Template> templateQueryWrapper = new LambdaQueryWrapper<>();
        templateQueryWrapper.eq(H2Template::getCode, ANCHOR);
        templateQueryWrapper.eq(H2Template::getType,ANCHOR);
        H2Template template = templateService.getOne(templateQueryWrapper);

        //处理合同细节
        String templateStr = template.getTemplate();
        String newTemplateStr = templateStr
                .replace("{startTime}", LocalDate.now().toString())
                .replace("{endTime}", LocalDate.now().plusMonths(6).toString())
                .replace("{monNum}", "6")
                .replace("{userName}", SecurityUtils.getUsername());


        //修改申请状态
        LambdaUpdateWrapper<H2AnchorApply> queryWrapper = new LambdaUpdateWrapper<>();
        queryWrapper.eq(H2AnchorApply::getUserId, userId).ne(H2AnchorApply::getStatus,AnchorApplyStatusEnum.FAIL.getCode());;

        H2AnchorApply newApply = new H2AnchorApply();
        newApply.setStatus(AnchorApplyStatusEnum.COMPLETE.getCode());
        newApply.setContract(newTemplateStr);
        newApply.setSignature(dto.getSignature());

        update(newApply,queryWrapper);

        //更改用户身份为主播
        userService.becomeAnchor(userId);
    }

    private AnchorMessageEnum parameterCheck(H2AnchorApplyDTO dto) {
        if(StringUtils.isEmpty(dto.getPassportPage()) && (StringUtils.isEmpty(dto.getCarAfter()) || StringUtils.isEmpty(dto.getCarBefore()))){
            return AnchorMessageEnum.CAR_NUMBER_IS_NULL;
        }
        return null;
    }
}

